home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch15 / Depth1.frm (.txt) < prev    next >
Visual Basic Form  |  1999-06-30  |  28KB  |  837 lines

  1. VERSION 5.00
  2. Begin VB.Form frmDepth1 
  3.    Appearance      =   0  'Flat
  4.    BackColor       =   &H00C0C0C0&
  5.    Caption         =   "Depth1"
  6.    ClientHeight    =   4065
  7.    ClientLeft      =   1410
  8.    ClientTop       =   540
  9.    ClientWidth     =   6330
  10.    BeginProperty Font 
  11.       Name            =   "MS Sans Serif"
  12.       Size            =   8.25
  13.       Charset         =   0
  14.       Weight          =   700
  15.       Underline       =   0   'False
  16.       Italic          =   0   'False
  17.       Strikethrough   =   0   'False
  18.    EndProperty
  19.    ForeColor       =   &H80000008&
  20.    KeyPreview      =   -1  'True
  21.    LinkTopic       =   "Form1"
  22.    PaletteMode     =   1  'UseZOrder
  23.    ScaleHeight     =   4065
  24.    ScaleWidth      =   6330
  25.    Begin VB.OptionButton optSolid 
  26.       Caption         =   "Sphere"
  27.       Height          =   255
  28.       Index           =   7
  29.       Left            =   0
  30.       TabIndex        =   9
  31.       Top             =   3240
  32.       Width           =   2055
  33.    End
  34.    Begin VB.OptionButton optSolid 
  35.       Caption         =   "Stellate Octahedron"
  36.       Height          =   255
  37.       Index           =   6
  38.       Left            =   0
  39.       TabIndex        =   8
  40.       Top             =   2880
  41.       Width           =   2055
  42.    End
  43.    Begin VB.OptionButton optSolid 
  44.       Caption         =   "Platonic Solids"
  45.       Height          =   255
  46.       Index           =   5
  47.       Left            =   0
  48.       TabIndex        =   7
  49.       Top             =   2520
  50.       Width           =   2055
  51.    End
  52.    Begin VB.OptionButton optSolid 
  53.       Caption         =   "6 Icosahedra"
  54.       Height          =   255
  55.       Index           =   4
  56.       Left            =   0
  57.       TabIndex        =   6
  58.       Top             =   2160
  59.       Width           =   2055
  60.    End
  61.    Begin VB.OptionButton optSolid 
  62.       Caption         =   "6 Dodecahedra"
  63.       Height          =   255
  64.       Index           =   3
  65.       Left            =   0
  66.       TabIndex        =   5
  67.       Top             =   1800
  68.       Width           =   2055
  69.    End
  70.    Begin VB.OptionButton optSolid 
  71.       Caption         =   "6 Octahedra"
  72.       Height          =   255
  73.       Index           =   2
  74.       Left            =   0
  75.       TabIndex        =   4
  76.       Top             =   1440
  77.       Width           =   2055
  78.    End
  79.    Begin VB.OptionButton optSolid 
  80.       Caption         =   "8 Cubes"
  81.       Height          =   255
  82.       Index           =   1
  83.       Left            =   0
  84.       TabIndex        =   3
  85.       Top             =   1080
  86.       Width           =   2055
  87.    End
  88.    Begin VB.OptionButton optSolid 
  89.       Caption         =   "6 Tetrahedra"
  90.       Height          =   255
  91.       Index           =   0
  92.       Left            =   0
  93.       TabIndex        =   2
  94.       Top             =   720
  95.       Width           =   2055
  96.    End
  97.    Begin VB.CheckBox chkRemoveBackfaces 
  98.       Caption         =   "Remove Backfaces"
  99.       Height          =   495
  100.       Left            =   0
  101.       TabIndex        =   1
  102.       Top             =   0
  103.       Width           =   2055
  104.    End
  105.    Begin VB.PictureBox picCanvas 
  106.       AutoRedraw      =   -1  'True
  107.       Height          =   3975
  108.       Left            =   2160
  109.       ScaleHeight     =   261
  110.       ScaleMode       =   3  'Pixel
  111.       ScaleWidth      =   261
  112.       TabIndex        =   0
  113.       Top             =   0
  114.       Width           =   3975
  115.    End
  116. Attribute VB_Name = "frmDepth1"
  117. Attribute VB_GlobalNameSpace = False
  118. Attribute VB_Creatable = False
  119. Attribute VB_PredeclaredId = True
  120. Attribute VB_Exposed = False
  121. Option Explicit
  122. ' Location of viewing eye.
  123. Private EyeR As Single
  124. Private EyeTheta As Single
  125. Private EyePhi As Single
  126. Private Const dtheta = PI / 20
  127. Private Const dphi = PI / 20
  128. Private Const Dr = 1
  129. ' Location of focus point.
  130. Private Const FocusX = 0#
  131. Private Const FocusY = 0#
  132. Private Const FocusZ = 0#
  133. Private Projector(1 To 4, 1 To 4) As Single
  134. Private Solids As Collection
  135. Private SelectedShape As Integer
  136. ' Sort the solids in depth-sort order.
  137. Private Sub SortSolids()
  138. Dim solid As Solid3d
  139. Dim ordered_solids As Collection
  140. Dim besti As Integer
  141. Dim bestz As Single
  142. Dim newz As Single
  143. Dim i As Integer
  144.     ' Compute each solid's Zmax value.
  145.     For Each solid In Solids
  146.         solid.SetZmax
  147.     Next solid
  148.     ' Sort the objects by their Zmax values.
  149.     Set ordered_solids = New Collection
  150.     Do While Solids.Count > 0
  151.         ' Find the face with the smallest Zmax
  152.         ' left in the Faces collection.
  153.         besti = 1
  154.         bestz = Solids(1).zmax
  155.         For i = 2 To Solids.Count
  156.             newz = Solids(i).zmax
  157.             If bestz > newz Then
  158.                 besti = i
  159.                 bestz = newz
  160.             End If
  161.         Next i
  162.         ' Add the best object to the sorted list.
  163.         ordered_solids.Add Solids(besti)
  164.         Solids.Remove besti
  165.     Loop
  166.     ' Replace the Solids collection with the
  167.     ' ordered_solids collection.
  168.     Set Solids = ordered_solids
  169. End Sub
  170. ' Draw the data.
  171. Private Sub DrawData(ByVal pic As PictureBox)
  172. Dim solid As Solid3d
  173. Dim X As Single
  174. Dim Y As Single
  175. Dim Z As Single
  176. Dim S(1 To 4, 1 To 4) As Single
  177. Dim T(1 To 4, 1 To 4) As Single
  178. Dim ST(1 To 4, 1 To 4) As Single
  179. Dim PST(1 To 4, 1 To 4) As Single
  180.     ' Prevent overflow errors when drawing lines
  181.     ' too far out of bounds.
  182.     On Error Resume Next
  183.     ' Uncull the solids.
  184.     For Each solid In Solids
  185.         solid.Culled = False
  186.     Next solid
  187.     ' Cull backfaces.
  188.     If chkRemoveBackfaces.value = vbChecked Then
  189.         m3SphericalToCartesian EyeR, EyeTheta, EyePhi, X, Y, Z
  190.         For Each solid In Solids
  191.             solid.Culled = False
  192.             solid.Cull X, Y, Z
  193.         Next solid
  194.     End If
  195.     ' Scale and translate so it looks OK in pixels.
  196.     m3Scale S, 100, -100, 1
  197.     m3Translate T, picCanvas.ScaleWidth / 2, picCanvas.ScaleHeight / 2, 0
  198.     m3MatMultiplyFull ST, S, T
  199.     m3MatMultiplyFull PST, Projector, ST
  200.     ' Transform the solids and clip faces.
  201.     For Each solid In Solids
  202.         solid.ApplyFull PST
  203.         ' Clip faces behind the center of projection.
  204.         solid.ClipEye EyeR
  205.     Next solid
  206.     ' Sort the solids if necessary.
  207.     If chkRemoveBackfaces.value = vbChecked Then
  208.         SortSolids
  209.     End If
  210.     ' Set the appropriate fill style.
  211.     If chkRemoveBackfaces.value = vbChecked Then
  212.         ' Fill to cover hidden surfaces.
  213.         pic.FillStyle = vbFSSolid
  214.         pic.FillColor = RGB(&H80, &HFF, &HFF)
  215.     Else
  216.         ' Do not fill so all lines are visible.
  217.         pic.FillStyle = vbFSTransparent
  218.     End If
  219.     ' Draw the solids.
  220.     pic.Cls
  221.     For Each solid In Solids
  222.         solid.Draw pic, EyeR
  223.     Next solid
  224.     pic.Refresh
  225. End Sub
  226. ' Redraw the picture with culling changed.
  227. Private Sub chkRemoveBackfaces_Click()
  228.     DrawData picCanvas
  229.     picCanvas.SetFocus
  230. End Sub
  231. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
  232.     Select Case KeyCode
  233.         Case vbKeyLeft
  234.             EyeTheta = EyeTheta - dtheta
  235.         
  236.         Case vbKeyRight
  237.             EyeTheta = EyeTheta + dtheta
  238.         
  239.         Case vbKeyUp
  240.             EyePhi = EyePhi - dphi
  241.         
  242.         Case vbKeyDown
  243.             EyePhi = EyePhi + dphi
  244.                 
  245.         Case Else
  246.             Exit Sub
  247.     End Select
  248.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  249.     DrawData picCanvas
  250. End Sub
  251. ' Make a sphere.
  252. Private Function Sphere(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal radius As Single, ByVal num_horizontal As Integer, ByVal num_vertical As Integer) As Solid3d
  253. Dim new_solid As Solid3d
  254. Dim T As Integer
  255. Dim theta1 As Single
  256. Dim theta2 As Single
  257. Dim dtheta As Single
  258. Dim P As Integer
  259. Dim phi1 As Single
  260. Dim phi2 As Single
  261. Dim dphi As Single
  262. Dim x11 As Single   ' xij: theta = i, phi = j
  263. Dim y11 As Single
  264. Dim z11 As Single
  265. Dim x12 As Single
  266. Dim y12 As Single
  267. Dim z12 As Single
  268. Dim x21 As Single
  269. Dim y21 As Single
  270. Dim z21 As Single
  271. Dim x22 As Single
  272. Dim y22 As Single
  273. Dim z22 As Single
  274. Dim R As Single
  275.     Set new_solid = New Solid3d
  276.     new_solid.IsConvex = True
  277.     theta1 = 0
  278.     dtheta = 2 * PI / num_horizontal
  279.     For T = 1 To num_horizontal
  280.         theta2 = theta1 + dtheta
  281.         phi1 = -PI / 2
  282.         dphi = PI / num_vertical
  283.         x11 = 0
  284.         y11 = -radius
  285.         z11 = 0
  286.         x21 = 0
  287.         y21 = -radius
  288.         z21 = 0
  289.         For P = 1 To num_vertical
  290.             phi2 = phi1 + dphi
  291.             y12 = radius * Sin(phi2)
  292.             R = radius * Cos(phi2)
  293.             x12 = R * Cos(theta1)
  294.             z12 = R * Sin(theta1)
  295.             y22 = radius * Sin(phi2)
  296.             R = radius * Cos(phi2)
  297.             x22 = R * Cos(theta2)
  298.             z22 = R * Sin(theta2)
  299.             If P = 1 Then
  300.                 ' Bottom triangle.
  301.                 new_solid.AddFace _
  302.                     Cx + x11, Cy + y11, Cz + z11, _
  303.                     Cx + x12, Cy + y12, Cz + z12, _
  304.                     Cx + x22, Cy + y22, Cz + z22
  305.             ElseIf P = num_vertical Then
  306.                 ' Top triangle.
  307.                 new_solid.AddFace _
  308.                     Cx + x11, Cy + y11, Cz + z11, _
  309.                     Cx + x12, Cy + y12, Cz + z12, _
  310.                     Cx + x21, Cy + y21, Cz + z21
  311.             Else
  312.                 ' Middle rectangle.
  313.                 new_solid.AddFace _
  314.                     Cx + x11, Cy + y11, Cz + z11, _
  315.                     Cx + x12, Cy + y12, Cz + z12, _
  316.                     Cx + x22, Cy + y22, Cz + z22, _
  317.                     Cx + x21, Cy + y21, Cz + z21
  318.             End If
  319.             x11 = x12
  320.             y11 = y12
  321.             z11 = z12
  322.             x21 = x22
  323.             y21 = y22
  324.             z21 = z22
  325.             phi1 = phi2
  326.         Next P
  327.         theta1 = theta2
  328.     Next T
  329.     Set Sphere = new_solid
  330. End Function
  331. Private Sub Form_KeyPress(KeyAscii As Integer)
  332.     Select Case KeyAscii
  333.         Case Asc("+")
  334.             EyeR = EyeR + Dr
  335.         
  336.         Case Asc("-")
  337.             EyeR = EyeR - Dr
  338.         
  339.         Case Else
  340.             Exit Sub
  341.     End Select
  342.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  343.     DrawData picCanvas
  344. End Sub
  345. Private Sub Form_Load()
  346.     ' Initialize the eye position.
  347.     EyeR = 10
  348.     EyeTheta = PI * 0.2
  349.     EyePhi = PI * 0.05
  350.     ' Initialize the projection transformation.
  351.     m3PProject Projector, m3Perspective, EyeR, EyePhi, EyeTheta, FocusX, FocusY, FocusZ, 0, 1, 0
  352.     ' Start with the tetrahedron.
  353.     Show
  354.     optSolid(0).value = True
  355. End Sub
  356. ' Create the data.
  357. Private Sub CreateData()
  358.     ' Create the new Solids collection.
  359.     Set Solids = New Collection
  360.     ' Create the solids.
  361.     Select Case SelectedShape
  362.         Case 0  ' Tetrahedra.
  363.             Solids.Add Tetrahedron(0.75, 0.5 + 0, 0, 0.4)
  364.             Solids.Add Tetrahedron(0, 0.5 + 0.75, 0, 0.4)
  365.             Solids.Add Tetrahedron(0, 0.5 + 0, 0.75, 0.4)
  366.             Solids.Add Tetrahedron(-0.75, 0.5 + 0, 0, 0.4)
  367.             Solids.Add Tetrahedron(0, 0.5 + -0.75, 0, 0.4)
  368.             Solids.Add Tetrahedron(0, 0.5 + 0, -0.75, 0.4)
  369.         Case 1  ' Cubes.
  370.             Solids.Add Cube(0.5, 0.5, 0.5, 0.4)
  371.             Solids.Add Cube(0.5, 0.5, -0.5, 0.4)
  372.             Solids.Add Cube(0.5, -0.5, 0.5, 0.4)
  373.             Solids.Add Cube(-0.5, 0.5, 0.5, 0.4)
  374.             Solids.Add Cube(0.5, -0.5, -0.5, 0.4)
  375.             Solids.Add Cube(-0.5, 0.5, -0.5, 0.4)
  376.             Solids.Add Cube(-0.5, -0.5, 0.5, 0.4)
  377.             Solids.Add Cube(-0.5, -0.5, -0.5, 0.4)
  378.         Case 2  ' Octahedra.
  379.             Solids.Add Octahedron(0.75, 0, 0, 0.4)
  380.             Solids.Add Octahedron(0, 0.75, 0, 0.4)
  381.             Solids.Add Octahedron(0, 0, 0.75, 0.4)
  382.             Solids.Add Octahedron(-0.75, 0, 0, 0.4)
  383.             Solids.Add Octahedron(0, -0.75, 0, 0.4)
  384.             Solids.Add Octahedron(0, 0, -0.75, 0.4)
  385.         Case 3  ' Dodecahedra.
  386.             Solids.Add Dodecahedron(0.75, 0, 0, 0.3)
  387.             Solids.Add Dodecahedron(0, 0.75, 0, 0.3)
  388.             Solids.Add Dodecahedron(0, 0, 0.75, 0.3)
  389.             Solids.Add Dodecahedron(-0.75, 0, 0, 0.3)
  390.             Solids.Add Dodecahedron(0, -0.75, 0, 0.3)
  391.             Solids.Add Dodecahedron(0, 0, -0.75, 0.3)
  392.         Case 4  ' Icosahedra.
  393.             Solids.Add Icosahedron(0.75, 0, 0, 0.4)
  394.             Solids.Add Icosahedron(0, 0.75, 0, 0.4)
  395.             Solids.Add Icosahedron(0, 0, 0.75, 0.4)
  396.             Solids.Add Icosahedron(-0.75, 0, 0, 0.4)
  397.             Solids.Add Icosahedron(0, -0.75, 0, 0.4)
  398.             Solids.Add Icosahedron(0, 0, -0.75, 0.4)
  399.         Case 5  ' Platonic solids.
  400.             Solids.Add Tetrahedron(0, 0.6 + 0.75, 0, 0.4)
  401.             Solids.Add Cube(0.75, 0, 0, 0.6)
  402.             Solids.Add Octahedron(0, 0, 0.75, 0.5)
  403.             Solids.Add Dodecahedron(-0.75, 0, 0, 0.4)
  404.             Solids.Add Icosahedron(0, 0, -0.75, 0.5)
  405.         Case 6  ' Stellate octahedron.
  406.             MakeStellate8 0.75
  407.         Case 7  ' Sphere.
  408.             Solids.Add Sphere(0, 0, 0, 1, 10, 10)
  409.     End Select
  410. End Sub
  411. ' Make a stellate octahedron.
  412. Private Sub MakeStellate8(ByVal side_scale As Single)
  413. Dim new_solid As Solid3d
  414.     Set new_solid = New Solid3d
  415.     Solids.Add new_solid
  416.     new_solid.IsConvex = True
  417.     new_solid.Stellate side_scale, _
  418.         0, side_scale, 0, _
  419.         0, 0, side_scale, _
  420.         side_scale, 0, 0
  421.     Set new_solid = New Solid3d
  422.     Solids.Add new_solid
  423.     new_solid.IsConvex = True
  424.     new_solid.Stellate side_scale, _
  425.         0, side_scale, 0, _
  426.         side_scale, 0, 0, _
  427.         0, 0, -side_scale
  428.     Set new_solid = New Solid3d
  429.     new_solid.IsConvex = True
  430.     Solids.Add new_solid
  431.     new_solid.Stellate side_scale, _
  432.         0, side_scale, 0, _
  433.         0, 0, -side_scale, _
  434.         -side_scale, 0, 0
  435.     Set new_solid = New Solid3d
  436.     Solids.Add new_solid
  437.     new_solid.IsConvex = True
  438.     new_solid.Stellate side_scale, _
  439.         0, side_scale, 0, _
  440.         -side_scale, 0, 0, _
  441.         0, 0, side_scale
  442.     Set new_solid = New Solid3d
  443.     Solids.Add new_solid
  444.     new_solid.IsConvex = True
  445.     new_solid.Stellate side_scale, _
  446.         0, -side_scale, 0, _
  447.         side_scale, 0, 0, _
  448.         0, 0, side_scale
  449.     Set new_solid = New Solid3d
  450.     Solids.Add new_solid
  451.     new_solid.IsConvex = True
  452.     new_solid.Stellate side_scale, _
  453.         0, -side_scale, 0, _
  454.         0, 0, -side_scale, _
  455.         side_scale, 0, 0
  456.     Set new_solid = New Solid3d
  457.     Solids.Add new_solid
  458.     new_solid.IsConvex = True
  459.     new_solid.Stellate side_scale, _
  460.         0, -side_scale, 0, _
  461.         -side_scale, 0, 0, _
  462.         0, 0, -side_scale
  463.     Set new_solid = New Solid3d
  464.     Solids.Add new_solid
  465.     new_solid.IsConvex = True
  466.     new_solid.Stellate side_scale, _
  467.         0, -side_scale, 0, _
  468.         0, 0, side_scale, _
  469.         -side_scale, 0, 0
  470. End Sub
  471. ' Make a dodecahedron.
  472. Private Function Dodecahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  473. Dim new_solid As Solid3d
  474. Dim theta1 As Single
  475. Dim theta2 As Single
  476. Dim s1 As Single
  477. Dim s2 As Single
  478. Dim c1 As Single
  479. Dim c2 As Single
  480. Dim M As Single
  481. Dim N As Single
  482. Dim S As Single
  483. Dim R As Single
  484. Dim A As Single
  485. Dim B As Single
  486. Dim C As Single
  487. Dim D As Single
  488. Dim H As Single
  489. Dim X As Single
  490. Dim Y As Single
  491. Dim y2 As Single
  492.     theta1 = PI * 0.4
  493.     theta2 = PI * 0.8
  494.     s1 = Sin(theta1)
  495.     c1 = Cos(theta1)
  496.     s2 = Sin(theta2)
  497.     c2 = Cos(theta2)
  498.     M = 1 - (2 - 2 * c1 - 4 * s1 * s1) / (2 * c1 - 2)
  499.     N = Sqr((2 - 2 * c1) - M * M) * (1 + (1 - c2) / (c1 - c2))
  500.     R = 2 / N * side_scale
  501.     S = R * Sqr(2 - 2 * c1)
  502.     A = R * s1
  503.     B = R * s2
  504.     C = R * c1
  505.     D = R * c2
  506.     H = R * (c1 - s1)
  507.     X = (R * R * (2 - 2 * c1) - 4 * A * A) / (2 * C - 2 * R)
  508.     Y = Sqr(S * S - (R - X) * (R - X))
  509.     y2 = Y * (1 - c2) / (c1 - c2)
  510.     Set new_solid = New Solid3d
  511.     new_solid.IsConvex = True
  512.     new_solid.AddFace _
  513.         Cx + C, Cy + side_scale, Cz + -A, _
  514.         Cx + D, Cy + side_scale, Cz + -B, _
  515.         Cx + D, Cy + side_scale, Cz + B, _
  516.         Cx + C, Cy + side_scale, Cz + A, _
  517.         Cx + R, Cy + side_scale, Cz + 0
  518.     new_solid.AddFace _
  519.         Cx + C, Cy + side_scale, Cz + A, _
  520.         Cx + X * c1, Cy + side_scale - Y, Cz + X * s1, _
  521.         Cx + -X * c2, Cy + side_scale - y2, Cz + X * s2, _
  522.         Cx + X, Cy + side_scale - Y, Cz + 0, _
  523.         Cx + R, Cy + side_scale, Cz + 0
  524.     new_solid.AddFace _
  525.         Cx + C, Cy + side_scale, Cz + A, _
  526.         Cx + D, Cy + side_scale, Cz + B, _
  527.         Cx + X * c2, Cy + side_scale - Y, Cz + X * s2, _
  528.         Cx + -X * c1, Cy + side_scale - y2, Cz + X * s1, _
  529.         Cx + X * c1, Cy + side_scale - Y, Cz + X * s1
  530.     new_solid.AddFace _
  531.         Cx + D, Cy + side_scale, Cz + B, _
  532.         Cx + D, Cy + side_scale, Cz + -B, _
  533.         Cx + X * c2, Cy + side_scale - Y, Cz + -X * s2, _
  534.         Cx + -X, Cy + side_scale - y2, Cz + 0, _
  535.         Cx + X * c2, Cy + side_scale - Y, Cz + X * s2
  536.     new_solid.AddFace _
  537.         Cx + D, Cy + side_scale, Cz + -B, _
  538.         Cx + C, Cy + side_scale, Cz + -A, _
  539.         Cx + X * c1, Cy + side_scale - Y, Cz + -X * s1, _
  540.         Cx + -X * c1, Cy + side_scale - y2, Cz + -X * s1, _
  541.         Cx + X * c2, Cy + side_scale - Y, Cz + -X * s2, -X * c1
  542.     new_solid.AddFace _
  543.         Cx + C, Cy + side_scale, Cz + -A, _
  544.         Cx + R, Cy + side_scale, Cz + 0, _
  545.         Cx + X, Cy + side_scale - Y, Cz + 0, _
  546.         Cx + -X * c2, Cy + side_scale - y2, Cz + -X * s2, _
  547.         Cx + X * c1, Cy + side_scale - Y, Cz + -X * s1
  548.     ' Bottom.
  549.     new_solid.AddFace _
  550.         Cx + -D, Cy + -side_scale, Cz + -B, _
  551.         Cx + -X * c2, Cy + side_scale - y2, Cz + -X * s2, _
  552.         Cx + X, Cy + side_scale - Y, Cz + 0, _
  553.         Cx + -X * c2, Cy + side_scale - y2, Cz + X * s2, _
  554.         Cx + -D, Cy + -side_scale, Cz + B
  555.     new_solid.AddFace _
  556.         Cx + -D, Cy + -side_scale, Cz + B, _
  557.         Cx + -X * c2, Cy + side_scale - y2, Cz + X * s2, _
  558.         Cx + X * c1, Cy + side_scale - Y, Cz + X * s1, _
  559.         Cx + -X * c1, Cy + side_scale - y2, Cz + X * s1, _
  560.         Cx + -C, Cy + -side_scale, Cz + A
  561.     new_solid.AddFace _
  562.         Cx + -C, Cy + -side_scale, Cz + A, _
  563.         Cx + -X * c1, Cy + side_scale - y2, Cz + X * s1, _
  564.         Cx + X * c2, Cy + side_scale - Y, Cz + X * s2, _
  565.         Cx + -X, Cy + side_scale - y2, Cz + 0, _
  566.         Cx + -R, Cy + -side_scale, Cz + 0
  567.     new_solid.AddFace _
  568.         Cx + -R, Cy + -side_scale, Cz + 0, _
  569.         Cx + -X, Cy + side_scale - y2, Cz + 0, _
  570.         Cx + X * c2, Cy + side_scale - Y, Cz + -X * s2, _
  571.         Cx + -X * c1, Cy + side_scale - y2, Cz + -X * s1, _
  572.         Cx + -C, Cy + -side_scale, Cz + -A
  573.     new_solid.AddFace _
  574.         Cx + -C, Cy + -side_scale, Cz + -A, _
  575.         Cx + -X * c1, Cy + side_scale - y2, Cz + -X * s1, _
  576.         Cx + X * c1, Cy + side_scale - Y, Cz + -X * s1, _
  577.         Cx + -X * c2, Cy + side_scale - y2, Cz + -X * s2, _
  578.         Cx + -D, Cy + -side_scale, Cz + -B
  579.     new_solid.AddFace _
  580.         Cx + -D, Cy + -side_scale, Cz + -B, _
  581.         Cx + -D, Cy + -side_scale, Cz + B, _
  582.         Cx + -C, Cy + -side_scale, Cz + A, _
  583.         Cx + -R, Cy + -side_scale, Cz + 0, _
  584.         Cx + -C, Cy + -side_scale, Cz + -A
  585.     Set Dodecahedron = new_solid
  586. End Function
  587. ' Make an icosahedron.
  588. Private Function Icosahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  589. Dim new_solid As Solid3d
  590. Dim theta1 As Single
  591. Dim theta2 As Single
  592. Dim s1 As Single
  593. Dim s2 As Single
  594. Dim c1 As Single
  595. Dim c2 As Single
  596. Dim A As Single
  597. Dim B As Single
  598. Dim C As Single
  599. Dim D As Single
  600. Dim H As Single
  601. Dim S As Single
  602. Dim R As Single
  603.     theta1 = PI * 0.4
  604.     theta2 = PI * 0.8
  605.     s1 = Sin(theta1)
  606.     c1 = Cos(theta1)
  607.     s2 = Sin(theta2)
  608.     c2 = Cos(theta2)
  609.     R = 2 / (2 * Sqr(1 - 2 * c1) + Sqr(3 / 4 * (2 - 2 * c1) - 2 * c2 - c2 * c2 - 1)) * side_scale
  610.     S = R * Sqr(2 - 2 * c1)
  611.     H = side_scale - Sqr(S * S - R * R)
  612.     A = R * s1
  613.     B = R * s2
  614.     C = R * c1
  615.     D = R * c2
  616.     ' Top.
  617.     Set new_solid = New Solid3d
  618.     new_solid.IsConvex = True
  619.     new_solid.AddFace _
  620.         Cx + 0, Cy + side_scale, 0 + Cz, _
  621.         Cx + C, Cy + H, A + Cz, _
  622.         Cx + R, Cy + H, 0 + Cz
  623.     new_solid.AddFace _
  624.         Cx + 0, Cy + side_scale, 0 + Cz, _
  625.         Cx + R, Cy + H, 0 + Cz, _
  626.         Cx + C, Cy + H, -A + Cz
  627.     new_solid.AddFace _
  628.         Cx + 0, Cy + side_scale, 0 + Cz, _
  629.         Cx + C, Cy + H, -A + Cz, _
  630.         Cx + D, Cy + H, -B + Cz
  631.     new_solid.AddFace _
  632.         Cx + 0, Cy + side_scale, 0 + Cz, _
  633.         Cx + D, Cy + H, -B + Cz, _
  634.         Cx + D, Cy + H, B + Cz
  635.     new_solid.AddFace _
  636.         Cx + 0, Cy + side_scale, 0 + Cz, _
  637.         Cx + D, Cy + H, B + Cz, _
  638.         Cx + C, Cy + H, A + Cz
  639.     ' Upper Middle.
  640.     new_solid.AddFace _
  641.         Cx + R, Cy + H, 0 + Cz, _
  642.         Cx + C, Cy + H, A + Cz, _
  643.         Cx + -D, Cy + -H, B + Cz
  644.     new_solid.AddFace _
  645.         Cx + C, Cy + H, A + Cz, _
  646.         Cx + D, Cy + H, B + Cz, _
  647.         Cx + -C, Cy + -H, A + Cz
  648.     new_solid.AddFace _
  649.         Cx + D, Cy + H, B + Cz, _
  650.         Cx + D, Cy + H, -B + Cz, _
  651.         Cx + -R, Cy + -H, 0 + Cz
  652.     new_solid.AddFace _
  653.         Cx + D, Cy + H, -B + Cz, _
  654.         Cx + C, Cy + H, -A + Cz, _
  655.         Cx + -C, Cy + -H, -A + Cz
  656.     new_solid.AddFace _
  657.         Cx + C, Cy + H, -A + Cz, _
  658.         Cx + R, Cy + H, 0 + Cz, _
  659.         Cx + -D, Cy + -H, -B + Cz
  660.     ' Lower Middle.
  661.     new_solid.AddFace _
  662.         Cx + R, Cy + H, 0 + Cz, _
  663.         Cx + -D, Cy + -H, B + Cz, _
  664.         Cx + -D, Cy + -H, -B + Cz
  665.     new_solid.AddFace _
  666.         Cx + C, Cy + H, A + Cz, _
  667.         Cx + -C, Cy + -H, A + Cz, _
  668.         Cx + -D, Cy + -H, B + Cz
  669.     new_solid.AddFace _
  670.         Cx + D, Cy + H, B + Cz, _
  671.         Cx + -R, Cy + -H, 0 + Cz, _
  672.         Cx + -C, Cy + -H, A + Cz
  673.     new_solid.AddFace _
  674.         Cx + D, Cy + H, -B + Cz, _
  675.         Cx + -C, Cy + -H, -A + Cz, _
  676.         Cx + -R, Cy + -H, 0 + Cz
  677.     new_solid.AddFace _
  678.         Cx + C, Cy + H, -A + Cz, _
  679.         Cx + -D, Cy + -H, -B + Cz, _
  680.         Cx + -C, Cy + -H, -A + Cz
  681.     ' Bottom.
  682.     new_solid.AddFace _
  683.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  684.         Cx + -D, Cy + -H, B + Cz, _
  685.         Cx + -C, Cy + -H, A + Cz
  686.     new_solid.AddFace _
  687.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  688.         Cx + -C, Cy + -H, A + Cz, _
  689.         Cx + -R, Cy + -H, 0 + Cz
  690.     new_solid.AddFace _
  691.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  692.         Cx + -R, Cy + -H, 0 + Cz, _
  693.         Cx + -C, Cy + -H, -A + Cz
  694.     new_solid.AddFace _
  695.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  696.         Cx + -C, Cy + -H, -A + Cz, _
  697.         Cx + -D, Cy + -H, -B + Cz
  698.     new_solid.AddFace _
  699.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  700.         Cx + -D, Cy + -H, -B + Cz, _
  701.         Cx + -D, Cy + -H, B + Cz
  702.     Set Icosahedron = new_solid
  703. End Function
  704. ' Make an octahedron.
  705. Private Function Octahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  706. Dim new_solid As Solid3d
  707.     ' Top.
  708.     Set new_solid = New Solid3d
  709.     new_solid.IsConvex = True
  710.     new_solid.AddFace _
  711.         Cx + 0, Cy + side_scale, 0 + Cz, _
  712.         Cx + side_scale, Cy + 0, 0 + Cz, _
  713.         Cx + 0, Cy + 0, -side_scale + Cz
  714.     new_solid.AddFace _
  715.         Cx + 0, Cy + side_scale, 0 + Cz, _
  716.         Cx + 0, Cy + 0, -side_scale + Cz, _
  717.         Cx + -side_scale, Cy + 0, 0 + Cz
  718.     new_solid.AddFace _
  719.         Cx + 0, Cy + side_scale, 0 + Cz, _
  720.         Cx + -side_scale, Cy + 0, 0 + Cz, _
  721.         Cx + 0, Cy + 0, side_scale + Cz
  722.     new_solid.AddFace _
  723.         Cx + 0, Cy + side_scale, 0 + Cz, _
  724.         Cx + 0, Cy + 0, side_scale + Cz, _
  725.         Cx + side_scale, Cy + 0, 0 + Cz
  726.     ' Bottom.
  727.     new_solid.AddFace _
  728.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  729.         Cx + side_scale, Cy + 0, 0 + Cz, _
  730.         Cx + 0, Cy + 0, side_scale + Cz
  731.     new_solid.AddFace _
  732.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  733.         Cx + 0, Cy + 0, side_scale + Cz, _
  734.         Cx + -side_scale, Cy + 0, 0 + Cz
  735.     new_solid.AddFace _
  736.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  737.         Cx + -side_scale, Cy + 0, 0 + Cz, _
  738.         Cx + 0, Cy + 0, -side_scale + Cz
  739.     new_solid.AddFace _
  740.         Cx + 0, Cy + -side_scale, 0 + Cz, _
  741.         Cx + 0, Cy + 0, -side_scale + Cz, _
  742.         Cx + side_scale, Cy + 0, 0 + Cz
  743.     Set Octahedron = new_solid
  744. End Function
  745. ' Make a cube with the indicated center and
  746. ' side length.
  747. Private Function Cube(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  748. Dim new_solid As Solid3d
  749. Dim s2 As Single
  750.     s2 = side_scale / 2
  751.     Set new_solid = New Solid3d
  752.     new_solid.IsConvex = True
  753.     ' Top.
  754.     new_solid.AddFace _
  755.         Cx + s2, Cy + s2, Cz + s2, _
  756.         Cx + s2, Cy + s2, Cz - s2, _
  757.         Cx - s2, Cy + s2, Cz - s2, _
  758.         Cx - s2, Cy + s2, Cz + s2
  759.     ' Positive X side.
  760.     new_solid.AddFace _
  761.         Cx + s2, Cy + s2, Cz + s2, _
  762.         Cx + s2, Cy - s2, Cz + s2, _
  763.         Cx + s2, Cy - s2, Cz - s2, _
  764.         Cx + s2, Cy + s2, Cz - s2
  765.     ' Positive Z side.
  766.     new_solid.AddFace _
  767.         Cx + s2, Cy + s2, Cz + s2, _
  768.         Cx - s2, Cy + s2, Cz + s2, _
  769.         Cx - s2, Cy - s2, Cz + s2, _
  770.         Cx + s2, Cy - s2, Cz + s2
  771.     ' Negative X side.
  772.     new_solid.AddFace _
  773.         Cx - s2, Cy - s2, Cz - s2, _
  774.         Cx - s2, Cy - s2, Cz + s2, _
  775.         Cx - s2, Cy + s2, Cz + s2, _
  776.         Cx - s2, Cy + s2, Cz - s2
  777.     ' Negative Z side.
  778.     new_solid.AddFace _
  779.         Cx - s2, Cy - s2, Cz - s2, _
  780.         Cx - s2, Cy + s2, Cz - s2, _
  781.         Cx + s2, Cy + s2, Cz - s2, _
  782.         Cx + s2, Cy - s2, Cz - s2
  783.     ' Bottom.
  784.     new_solid.AddFace _
  785.         Cx - s2, Cy - s2, Cz - s2, _
  786.         Cx + s2, Cy - s2, Cz - s2, _
  787.         Cx + s2, Cy - s2, Cz + s2, _
  788.         Cx - s2, Cy - s2, Cz + s2
  789.     Set Cube = new_solid
  790. End Function
  791. ' Make a tetrahedron.
  792. Private Function Tetrahedron(ByVal Cx As Single, ByVal Cy As Single, ByVal Cz As Single, ByVal side_scale As Single) As Solid3d
  793. Dim new_solid As Solid3d
  794. Dim S As Single
  795. Dim A As Single
  796. Dim B As Single
  797. Dim C As Single
  798. Dim D As Single
  799.     S = Sqr(6) * side_scale
  800.     A = S / Sqr(3)
  801.     B = -A / 2
  802.     C = A * Sqr(2) - 1
  803.     D = S / 2
  804.     Set new_solid = New Solid3d
  805.     new_solid.IsConvex = True
  806.     new_solid.AddFace _
  807.         Cx + 0, Cy + C, 0 + Cz, _
  808.         Cx + A, Cy + -1, 0 + Cz, _
  809.         Cx + B, Cy + -1, -D + Cz
  810.     new_solid.AddFace _
  811.         Cx + 0, Cy + C, 0 + Cz, _
  812.         Cx + B, Cy + -1, -D + Cz, _
  813.         Cx + B, Cy + -1, D + Cz
  814.     new_solid.AddFace _
  815.         Cx + 0, Cy + C, 0 + Cz, _
  816.         Cx + B, Cy + -1, D + Cz, _
  817.         Cx + A, Cy + -1, 0 + Cz
  818.     new_solid.AddFace _
  819.         Cx + A, Cy + -1, 0 + Cz, _
  820.         Cx + B, Cy + -1, D + Cz, _
  821.         Cx + B, Cy + -1, -D + Cz
  822.     Set Tetrahedron = new_solid
  823. End Function
  824. ' Make the drawing areas as large as possible.
  825. Private Sub Form_Resize()
  826. Dim wid As Single
  827.     wid = ScaleWidth - picCanvas.Left
  828.     If wid < 120 Then wid = 120
  829.     picCanvas.Move picCanvas.Left, 0, wid, ScaleHeight
  830. End Sub
  831. Private Sub optSolid_Click(Index As Integer)
  832.     SelectedShape = Index
  833.     CreateData
  834.     DrawData picCanvas
  835.     picCanvas.SetFocus
  836. End Sub
  837.